package top.yuhaitao.core.thread;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * execute 无返回值（利用成员变量获取值，需要加锁）
 * submit 有返回值，同步等待每个线程的结果。
 */
public class ThreadPool {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
//        createCachedThreadPool();

//        createFixedThreadPool();


        createFixedThreadPool1();


    }

    /**
     * 缓存线程池
     */
    private static void createCachedThreadPool() {
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 5; i++) {
            executorService.execute(() -> {
                System.out.println("thread name is :" + Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
//        executorService.shutdown();
    }

    /**
     * 固定的线程池
     */
    private static void createFixedThreadPool() throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(4);
        for (int i = 0; i < 10; i++) {
            Future<String> submit = executorService.submit(() -> {
                String s = "b-" + Thread.currentThread().getName();
                Thread.sleep(1000);
                return s;
            });
            System.out.println(submit.get());
        }
        executorService.shutdown();
    }


    /**
     * 利用变量获取结果
     */
    private static void createFixedThreadPool1() throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(4);
        List<Future<?>> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Future<Integer> submit = executorService.submit(new TaskCallable<>(i));
            list.add(submit);
        }

        for (Future<?> future : list) {
            System.out.println(future.isDone());
        }
        executorService.shutdown();
    }

    static class TaskCallable<T> implements Callable<T> {

        T id;

        public TaskCallable(T id) {
            this.id = id;
        }

        @Override
        public T call() throws InterruptedException {
            Thread.sleep(1000);
            String name = Thread.currentThread().getName();
            LocalDateTime now = LocalDateTime.now();
            System.out.println("threadName: " + name + ", time: " + now + ", id: " + id);
            return id;
        }

        @Override
        public String toString() {
            return "TaskCallable{" +
                    "id=" + id +
                    '}';
        }
    }
}
